package controllers

import (
	"fmt"
	"github.com/astaxie/beego"
	"nway_dsr/dsr/libs"
	"nway_dsr/dsr/models"
	"strconv"
	"strings"
	"time"
	"math/rand"
	"errors"
	"os/exec"
	"bufio"
	"io"
	"nway_dsr/nway_dsr/utils/nway_uuid"
)

type BaseController struct {
	beego.Controller
	controllerName string
	actionName     string
	userId         int64
	isOrg          bool
	userName       string
	loginName      string
	pageSize       int
	allowUrl       string
}

const (
	MSG_OK  = 0
	MSG_ERR = -1
)

//前期准备
func (self *BaseController) Prepare() {
	self.pageSize = 40
	controllerName, actionName := self.GetControllerAndAction()
	self.controllerName = strings.ToLower(controllerName[0 : len(controllerName)-10])
	self.actionName = strings.ToLower(actionName)
	self.Data["version"] = beego.AppConfig.String("version")
	self.Data["siteName"] = beego.AppConfig.String("site.name")
	self.Data["curRoute"] = self.controllerName + "." + self.actionName
	self.Data["curController"] = self.controllerName
	self.Data["curAction"] = self.actionName
	self.Data["loginUserId"] = self.userId
	self.Data["loginUserName"] = self.userName
	self.auth()
}

func (self *BaseController) XLogin(){
	username := self.GetString("username")
	password := self.GetString("password")
	if username != "" && password != "" {
		user, err := models.AdminGetByName(username)
		if err!=nil {
			self.ajaxMsg("没有该账号",MSG_OK)
		}else {
			salt:=strings.TrimSpace(user.Salt)
			if  user.Password != libs.Md5([]byte(password+salt)) {
				self.ajaxMsg("帐号或密码错误",MSG_OK)
			}else {
				//加密
				authkey := libs.Md5([]byte(self.getClientIp() + "|" + user.Password + user.Salt))
				self.ajaxMsg(authkey,MSG_OK)
			}
		}
	}
	self.ajaxMsg("输入账号密码",MSG_ERR)
}

//权限判断
func (self *BaseController) auth() {
	arr := strings.Split(self.Ctx.GetCookie("auth123"), "|")
	if(self.actionName == "xlogin"){
		return
	}
	if len(arr) == 2 { //取出cookie里面的加密后的字符串
		id, _ := strconv.ParseInt(arr[0], 10, 64)
		password := arr[1]
		user, err := models.AdminGetById(id) //搜索这个id的user情况
		if err == nil && password == libs.Md5([]byte(self.getClientIp()+"|"+user.Password+user.Salt)) {
			self.userId = user.Id
		} else {
			self.Ctx.SetCookie("auth123", "")
			return
			self.redirect("/login_out")
			self.Ctx.WriteString("改过密码了")
			return
		}
	}
	if self.userId == 0 && (self.controllerName != "login" && self.actionName != "loginin") {
		self.redirect(beego.URLFor("LoginController.LoginIn"))
	}

}

func (self *BaseController) UploadFile(dir, fileName string) (string,string, error){

	timestamp := time.Now().Unix()
	time := strconv.FormatInt(timestamp, 10)
	file, header, err := self.GetFile(fileName) //获取文件
	var str = " "
	var ptsh = time + strconv.FormatInt(int64(rand.Intn(10000)), 10)
	if strings.Contains(header.Filename, ".wav") {
		str = ptsh + ".wav"
	} else if strings.Contains(header.Filename, ".mp3") {
		str = ptsh + ".mp3"
	} else if strings.Contains(header.Filename, ".m4a") {
		str = ptsh + ".m4a"
	} else if strings.Contains(header.Filename, ".xlsx"){
		str =  "file.xlsx"
	}else {
		return "错误格式","", errors.New("错误格式")
	}
	path := dir + str //文件目录 暂时'用户信息欠缺

	file.Close() //关闭上传的文件，不然的话会出现临时文件不能清除的情况
	self.SaveToFile(fileName, path)
	//保存文件
	if strings.Contains(header.Filename, ".mp3") || strings.Contains(header.Filename, ".m4a") {
		params := []string{ "-y","-i",path,"-ar","8000","-ac","2","-acodec","pcm_s16le", dir + ptsh + ".wav"}
		execCommand("ffmpeg", params)
	}
	if strings.Contains(header.Filename, ".mp3") || strings.Contains(header.Filename, ".m4a") || strings.Contains(header.Filename, ".wav") {
		uuid:=nway_uuid.GetUUId()
		fmt.Println(strings.Replace(dir + ptsh + ".wav", "./", "/opt/nway_fs_dsr/web/", -1),uuid)
		params := []string{ strings.Replace(dir + ptsh + ".wav", "./", "/opt/nway_fs_dsr/web/", -1),uuid}
		err = models.InsertCdr(uuid)
		if err != nil {
			fmt.Println(err)
		}
		go execCommand("../offline_qc", params)
		return dir + ptsh + ".wav",uuid, err
	}
	return path,"", nil

}

func execCommand(commandName string, params []string) bool {
	//函数返回一个*Cmd，用于使用给出的参数执行name指定的程序
	cmd := exec.Command(commandName, params...)

	//显示运行的命令
	fmt.Println(cmd.Args)
	//StdoutPipe方法返回一个在命令Start后与命令标准输出关联的管道。Wait方法获知命令结束后会关闭这个管道，一般不需要显式的关闭该管道。
	stdout, err := cmd.StdoutPipe()

	if err != nil {
		fmt.Println(err)
		return false
	}

	cmd.Start()
	//创建一个流来读取管道内内容，这里逻辑是通过一行一行的读取的
	reader := bufio.NewReader(stdout)

	//实时循环读取输出流中的一行内容
	for {
		line, err2 := reader.ReadString('\n')
		if err2 != nil || io.EOF == err2 {
			break
		}
		fmt.Println(line)
	}

	//阻塞直到该命令执行完成，该命令必须是被Start方法开始执行的
	cmd.Wait()
	return true
}

func (c *BaseController) Index() {
	c.Data["SideMenu1"] = []map[string]string{
		{"name": "功能", "pid": "1"},
		{"name": "用户管理", "pid": "2"},
	}
	c.Data["SideMenu2"] = []map[string]string{
		{"name": "通话详单", "id": "1","pid":"1", "url": "cdr/cdr"},
		{"name": "用户列表", "id": "2","pid":"2", "url": "admin/admin"},
		{"name": "禁忌词汇", "id": "3","pid":"1", "url": "keywords/list?type=1"},
		{"name": "常规词汇", "id": "4","pid":"1", "url": "keywords/list?type=2"},

	}
	c.Data["siteName"] = "质检系统"
	c.Data["version"] = "1.0.0"
	c.Data["loginUserName"] = "admin"
	c.TplName = "main/index.html"
}

// 重定向
func (self *BaseController) redirect(url string) {
	self.Redirect(url, 302)
	self.StopRun()
}

//时间格式化
func (self *BaseController) FormatTimes(strTime string) string {
	toTime, _ := time.Parse("2006-01-02 15:04:05", strTime)
	toStr := toTime.Format("2006-01-02 15:04:05")
	return toStr
}

// 是否POST提交
func (self *BaseController) isPost() bool {
	return self.Ctx.Request.Method == "POST"
}

//加载模板
func (self *BaseController) display(tpl ...string) {
	var tplname string
	fmt.Println(self.controllerName + "/" + self.actionName + ".html")

	if len(tpl) > 0 {
		tplname = strings.Join([]string{tpl[0], "html"}, ".")
	} else {
		tplname = self.controllerName + "/" + self.actionName + ".html"
	}
	self.Layout = "main/layout.html"
	self.TplName = tplname
}

//获取用户IP地址
func (self *BaseController) getClientIp() string {
	s := strings.Split(self.Ctx.Request.RemoteAddr, ":")
	return s[0]
}

//ajax返回
func (self *BaseController) ajaxMsg(msg interface{}, msgno int) {
	out := make(map[string]interface{})
	out["status"] = msgno
	out["message"] = msg
	self.Data["json"] = out
	self.ServeJSON()
	self.StopRun()
}

//ajax返回 列表
func (self *BaseController) ajaxList(msg interface{}, msgno int, count int64, data interface{}) {
	out := make(map[string]interface{})
	out["code"] = msgno
	out["msg"] = msg
	out["count"] = count
	out["data"] = data
	self.Data["json"] = out
	self.ServeJSON()
	self.StopRun()
}
